#include <asm/hvm/vacpi.h>
#include <asm/hvm/support.h>
#include <public/hvm/save.h>
+#include <public/arch-ia64/hvm/memmap.h>
#include <public/arch-ia64/sioemu.h>
#include <asm/sioemu.h>
return;
}
-static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 pte)
+static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 iot)
{
- unsigned long iot = pte & GPFN_IO_MASK;
-
- perfc_incra(vmx_mmio_access, iot >> 56);
+ perfc_incra(vmx_mmio_access, iot & 0x7);
switch (iot) {
case GPFN_PIB:
if (ma != 4)
else
*dest = vlsapic_read(vcpu, src_pa, s);
break;
- case GPFN_GFW:
- break;
case GPFN_IOSAPIC:
if (!dir)
viosapic_write(vcpu, src_pa, s, *dest);
/*
dir 1: read 0:write
*/
-void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte)
+void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 iot)
{
REGS *regs;
IA64_BUNDLE bundle;
}
if (vcpu->domain->arch.is_sioemu) {
- unsigned long iot = pte & GPFN_IO_MASK;
-
if (iot != GPFN_PIB && iot != GPFN_IOSAPIC) {
sioemu_io_emulate(padr, data, data1, update_word);
return;
}
if (size == 4) {
- mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, pte);
+ mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, iot);
size = 3;
}
- mmio_access(vcpu, padr, &data, 1 << size, ma, dir, pte);
+ mmio_access(vcpu, padr, &data, 1 << size, ma, dir, iot);
emulate_io_update(vcpu, update_word, data, data1);
}
unsigned long i;
int res;
+ /* Convert to ppn. */
+ type <<= PAGE_SHIFT;
+
/* Check type. */
- if (type == 0 || (type & GPFN_IO_MASK) != type)
+ if (type == 0 || (type & _PAGE_PPN_MASK) != type)
return -EINVAL;
if ((start & (PAGE_SIZE -1)) || (size & (PAGE_SIZE - 1)))
return -EINVAL;
/* Set. */
for (i = start; i < start + size; i += PAGE_SIZE) {
- res = __assign_domain_page(d, i, type, ASSIGN_writable);
+ res = __assign_domain_page(d, i, type, ASSIGN_writable | ASSIGN_io);
if (res != 0)
return res;
}
#include <xen/domain.h>
#include <asm/hvm/support.h>
#include <public/hvm/save.h>
+#include <public/arch-ia64/hvm/memmap.h>
#ifdef IPI_DEBUG
#define IPI_DPRINTK(x...) printk(x)
thash_purge_entries(vcpu, va, ps);
gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
gpte = lookup_domain_mpa(vcpu->domain, gpfn, NULL);
- if (gpte & GPFN_IO_MASK)
+ if (gpte & _PAGE_IO)
pte |= VTLB_PTE_IO;
vcpu_get_rr(vcpu, va, &rid);
rid &= RR_RID_MASK;
return IA64_FAULT;
}
pte = lookup_domain_mpa(v->domain, pa_clear_uc(vadr), NULL);
- if (v->domain != dom0 && (pte & GPFN_IO_MASK)) {
- emulate_io_inst(v, pa_clear_uc(vadr), 4, pte);
+ if (v->domain != dom0 && (pte & _PAGE_IO)) {
+ emulate_io_inst(v, pa_clear_uc(vadr), 4,
+ (pte & _PFN_MASK) >> PAGE_SHIFT);
return IA64_FAULT;
}
physical_tlb_miss(v, vadr, type);
}
gppa = thash_translate(data, vadr);
pte = lookup_domain_mpa(v->domain, gppa, NULL);
- if (pte & GPFN_IO_MASK) {
+ if (pte & _PAGE_IO) {
if (misr.sp)
panic_domain(NULL, "ld.s on I/O page not with UC attr."
" pte=0x%lx\n", data->page_flags);
if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3))
- emulate_io_inst(v, gppa, data->ma, pte);
+ emulate_io_inst(v, gppa, data->ma,
+ (pte & _PFN_MASK) >> PAGE_SHIFT);
else {
vcpu_set_isr(v, misr.val);
data_access_rights(v, vadr);
#include <public/xen.h>
#include <public/hvm/ioreq.h>
#include <public/event_channel.h>
+#include <public/arch-ia64/hvm/memmap.h>
#include <asm/vmx_phy_mode.h>
#include <asm/processor.h>
#include <asm/vmx.h>
} io_range_t;
static const io_range_t io_ranges[] = {
- {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER},
- {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO},
- {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO},
- {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC},
- {PIB_START, PIB_SIZE, GPFN_PIB},
+ {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER << PAGE_SHIFT},
+ {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO << PAGE_SHIFT},
+ {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO << PAGE_SHIFT},
+ {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC << PAGE_SHIFT},
+ {PIB_START, PIB_SIZE, GPFN_PIB << PAGE_SHIFT},
};
// The P2M table is built in libxc/ia64/xc_ia64_hvm_build.c @ setup_guest()
for (j = io_ranges[i].start;
j < io_ranges[i].start + io_ranges[i].size; j += PAGE_SIZE)
(void)__assign_domain_page(d, j, io_ranges[i].type,
- ASSIGN_writable);
+ ASSIGN_writable | ASSIGN_io);
}
}
phy_pte.val = pte;
paddr = ((pte & _PAGE_PPN_MASK) & ps_mask) | (va & ~ps_mask);
maddr = lookup_domain_mpa(d, paddr, NULL);
- if (maddr & GPFN_IO_MASK)
+ if (maddr & _PAGE_IO)
return -1;
/* Ensure WB attribute if pte is related to a normal mem page,
res |= flags & ASSIGN_tlb_track ? _PAGE_TLB_TRACKING: 0;
#endif
res |= flags & ASSIGN_pgc_allocated ? _PAGE_PGC_ALLOCATED: 0;
+ res |= flags & ASSIGN_io ? _PAGE_IO: 0;
return res;
}
{
struct page_info* page = mfn_to_page(physaddr >> PAGE_SHIFT);
- BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM);
+ BUG_ON((physaddr & _PAGE_PPN_MASK) != physaddr);
BUG_ON(page->count_info != (PGC_allocated | 1));
set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT);
// because __assign_domain_page() uses set_pte_rel() which has
#define _PAGE_PGC_ALLOCATED_BIT 59 /* _PGC_allocated */
#define _PAGE_PGC_ALLOCATED (__IA64_UL(1) << _PAGE_PGC_ALLOCATED_BIT)
-/* domVTI */
-#define GPFN_MEM (0UL << 60) /* Guest pfn is normal mem */
-#define GPFN_FRAME_BUFFER (1UL << 60) /* VGA framebuffer */
-#define GPFN_LOW_MMIO (2UL << 60) /* Low MMIO range */
-#define GPFN_PIB (3UL << 60) /* PIB base */
-#define GPFN_IOSAPIC (4UL << 60) /* IOSAPIC base */
-#define GPFN_LEGACY_IO (5UL << 60) /* Legacy I/O base */
-#define GPFN_GFW (6UL << 60) /* Guest Firmware */
-#define GPFN_HIGH_MMIO (7UL << 60) /* High MMIO range */
-
-#define GPFN_IO_MASK (7UL << 60) /* Guest pfn is I/O type */
+
+#define _PAGE_IO_BIT 60
+#define _PAGE_IO (__IA64_UL(1) << _PAGE_IO_BIT)
#else
#define _PAGE_PROTNONE (__IA64_UL(1) << 63)
#define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0)
#ifdef XEN
#define pte_pgc_allocated(pte) ((pte_val(pte) & _PAGE_PGC_ALLOCATED) != 0)
-#define pte_mem(pte) (!(pte_val(pte) & GPFN_IO_MASK) && !pte_none(pte))
+#define pte_mem(pte) (!(pte_val(pte) & _PAGE_IO) && !pte_none(pte))
#endif
/*
* Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the
extern void free_domain_tlb(struct vcpu *v);
extern thash_data_t * vhpt_lookup(u64 va);
extern unsigned long fetch_code(struct vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle);
-extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma, u64 pte);
+extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma, u64 iot);
extern void emulate_io_update(struct vcpu *vcpu, u64 word, u64 d, u64 d1);
extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa,
/* WARNING: before changing this, check that shared_info fits on a page */
#define MAX_VIRT_CPUS 64
+/* IO ports location for PV. */
+#define IO_PORTS_PADDR 0x00000ffffc000000UL
+#define IO_PORTS_SIZE 0x0000000004000000UL
+
#ifndef __ASSEMBLY__
#define __anonymous_union __extension__ union
#define INVALID_MFN (~0UL)
-#define MEM_G (1UL << 30)
-#define MEM_M (1UL << 20)
-#define MEM_K (1UL << 10)
-
-/* Guest physical address of IO ports space. */
-#define IO_PORTS_PADDR 0x00000ffffc000000UL
-#define IO_PORTS_SIZE 0x0000000004000000UL
-
-#define MMIO_START (3 * MEM_G)
-#define MMIO_SIZE (512 * MEM_M)
-
-#define VGA_IO_START 0xA0000UL
-#define VGA_IO_SIZE 0x20000
-
-#define LEGACY_IO_START (MMIO_START + MMIO_SIZE)
-#define LEGACY_IO_SIZE (64*MEM_M)
-
-#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
-#define IO_PAGE_SIZE XEN_PAGE_SIZE
-
-#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
-#define STORE_PAGE_SIZE XEN_PAGE_SIZE
-
-#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE)
-#define BUFFER_IO_PAGE_SIZE XEN_PAGE_SIZE
-
-#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
-#define BUFFER_PIO_PAGE_SIZE XEN_PAGE_SIZE
-
-#define IO_SAPIC_START 0xfec00000UL
-#define IO_SAPIC_SIZE 0x100000
-
-#define PIB_START 0xfee00000UL
-#define PIB_SIZE 0x200000
-
-#define GFW_START (4*MEM_G -16*MEM_M)
-#define GFW_SIZE (16*MEM_M)
-
-/* Nvram belongs to GFW memory space */
-#define NVRAM_SIZE (MEM_K * 64)
-#define NVRAM_START (GFW_START + 10 * MEM_M)
-
-#define NVRAM_VALID_SIG 0x4650494e45584948 // "HIXENIPF"
-struct nvram_save_addr {
- unsigned long addr;
- unsigned long signature;
-};
-
struct pt_fpreg {
union {
unsigned long bits[2];
/* Internal only: associated with PGC_allocated bit */
#define _ASSIGN_pgc_allocated 3
#define ASSIGN_pgc_allocated (1UL << _ASSIGN_pgc_allocated)
+/* Page is an IO page. */
+#define _ASSIGN_io 4
+#define ASSIGN_io (1UL << _ASSIGN_io)
/* This structure has the same layout of struct ia64_boot_param, defined in
<asm/system.h>. It is redefined here to ease use. */
#endif /* __ASSEMBLY__ */
#endif /* XEN */
+#ifndef __ASSEMBLY__
+#include "arch-ia64/hvm/memmap.h"
+#endif
+
#endif /* __HYPERVISOR_IF_IA64_H__ */
/*
--- /dev/null
+/******************************************************************************
+ * memmap.h
+ *
+ * Copyright (c) 2008 Tristan Gingold <tgingold AT free fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
+#define __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
+
+#define MEM_G (1UL << 30)
+#define MEM_M (1UL << 20)
+#define MEM_K (1UL << 10)
+
+/* Guest physical address of IO ports space. */
+#define MMIO_START (3 * MEM_G)
+#define MMIO_SIZE (512 * MEM_M)
+
+#define VGA_IO_START 0xA0000UL
+#define VGA_IO_SIZE 0x20000
+
+#define LEGACY_IO_START (MMIO_START + MMIO_SIZE)
+#define LEGACY_IO_SIZE (64 * MEM_M)
+
+#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
+#define IO_PAGE_SIZE XEN_PAGE_SIZE
+
+#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
+#define STORE_PAGE_SIZE XEN_PAGE_SIZE
+
+#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE)
+#define BUFFER_IO_PAGE_SIZE XEN_PAGE_SIZE
+
+#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
+#define BUFFER_PIO_PAGE_SIZE XEN_PAGE_SIZE
+
+#define IO_SAPIC_START 0xfec00000UL
+#define IO_SAPIC_SIZE 0x100000
+
+#define PIB_START 0xfee00000UL
+#define PIB_SIZE 0x200000
+
+#define GFW_START (4 * MEM_G - 16 * MEM_M)
+#define GFW_SIZE (16 * MEM_M)
+
+/* domVTI */
+#define GPFN_FRAME_BUFFER 0x1 /* VGA framebuffer */
+#define GPFN_LOW_MMIO 0x2 /* Low MMIO range */
+#define GPFN_PIB 0x3 /* PIB base */
+#define GPFN_IOSAPIC 0x4 /* IOSAPIC base */
+#define GPFN_LEGACY_IO 0x5 /* Legacy I/O base */
+#define GPFN_HIGH_MMIO 0x6 /* High MMIO range */
+
+/* Nvram belongs to GFW memory space */
+#define NVRAM_SIZE (MEM_K * 64)
+#define NVRAM_START (GFW_START + 10 * MEM_M)
+
+#define NVRAM_VALID_SIG 0x4650494e45584948 /* "HIXENIPF" */
+struct nvram_save_addr {
+ unsigned long addr;
+ unsigned long signature;
+};
+
+#endif /* __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */